package priorityqueue

import (
	"Go-miniSTL/comparable"
	"container/heap"
)

type SortList []comparable.Comparable

type PriorityQueue struct {
	data *SortList
}

func (c *SortList) ILoc(index int) *comparable.Comparable {
	return &(*c)[index]
}

func (c *SortList) Less(i, j int) bool {
	x := *c.ILoc(i)
	return x.Less(*(c.ILoc(j)))
}

func (c *SortList) Swap(i, j int) {
	*(c.ILoc(i)), *(c.ILoc(j)) = *(c.ILoc(j)), *(c.ILoc(i))
}

func (c *SortList) Len() int {
	return len(*c)
}

func (c *SortList) Push(x interface{}) {
	*c = append(*c, x.(comparable.Comparable))
}

func (c *SortList) Pop() interface{} {
	n := c.Len() - 1
	x := *(c.ILoc(n))
	*c = (*c)[0:n]
	return x
}

func New() PriorityQueue {
	p := make(SortList, 0)
	return PriorityQueue{data: &p}
}

func (c PriorityQueue) Push(x comparable.Comparable) {
	heap.Push(c.data, x)
}

func (c PriorityQueue) Pop() interface{} {
	if len(*c.data) == 0 {
		return nil
	}
	return heap.Pop(c.data)
}

func (c PriorityQueue) Top() interface{} {
	if len(*c.data) == 0 {
		return nil
	}
	return (*c.data)[0]
}

func (c PriorityQueue) Len() int {
	return len(*c.data)
}
